package com.lzc.springMvcPart;

import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.MethodParameter;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.annotation.RequestParamMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.handler.DispatcherServletWebRequest;
import org.springframework.web.servlet.mvc.method.annotation.PathVariableMethodArgumentResolver;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 自带的方法参数解析器学习
 */
public class MethodArgumentResolverTest {

    public static void main(String[] args) throws Exception {

        List<HandlerMethodArgumentResolver> list = new ArrayList<>();
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
        DefaultListableBeanFactory beanFactory = context.getDefaultListableBeanFactory();

        // 请求对象
        DispatcherServletWebRequest request = new DispatcherServletWebRequest(MockRequest.getRequest());

        // 参数解析器对象
        list.add(new RequestParamMethodArgumentResolver(null, false));
        list.add(new PathVariableMethodArgumentResolver());


        // 获取要被执行的HandlerMethod
        HandlerMethod handlerMethod = new HandlerMethod(new MyController(), MyController.class.getMethod("one", String.class, int.class,int.class));
        // 获取所有参数对象
        MethodParameter[] methodParameters = handlerMethod.getMethodParameters();
        // 遍历每一个参数
        for (MethodParameter methodParameter : methodParameters) {
            methodParameter.initParameterNameDiscovery(new DefaultParameterNameDiscoverer());

            for (HandlerMethodArgumentResolver resolver : list) {
                if (resolver.supportsParameter(methodParameter)) {
                    Object result = resolver.resolveArgument(methodParameter,
                            null,
                            request,
                            null);
                    System.out.println(result.getClass());
                    System.out.println(methodParameter.getParameterIndex()+". "+
                            methodParameter.getParameterType().getSimpleName()+" "+
                            methodParameter.getParameterName()+"->"+
                            result);
                    break;
                }
            }

        }

    }

    // 控制器类
    static class MyController{
        public void one(@RequestParam("name") String name,
                        @RequestParam("age") int age,
                        @PathVariable("id") int id){}
    }

    // 模拟请求数据
    static class MockRequest{
        static MockHttpServletRequest getRequest(){
            MockHttpServletRequest request = new MockHttpServletRequest();
            request.setParameter("name","zhangsan");
            request.setParameter("age","18");

            HashMap<String, Object> map = new HashMap<>();
            map.put("id","1");
            request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, map);



            return request;
        }
    }

    @Configuration
    static class Config{

    }
}
